package com.alks.function.controller.task;


import com.alks.common.aop.RedisLock;
import com.alks.entity.data.entity.YearDay;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.finance.statement.GenerateProdReportMapper;
import com.alks.function.service.biocontrol.factoryQuery.IStkAccService;
import com.alks.function.service.finance.statement.GenerateProdReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * 报表分析
 * 部门生产状况
 */
@Component
@Slf4j
@EnableScheduling
@EnableAsync
public class DhDeptProdTask {

    @Autowired
    private GenerateProdReportMapper generateProdReportMapper;

    @Autowired
    private  PcLotHeadMapper pcLotHeadMapper;

    @Autowired
    private GenerateProdReportService generateProdReportService;

    @Autowired
    private IStkAccService stkAccService;


    /**
     * 部门生产状况
     * 2.1 月/月生产状况
     * 每天4点更新昨天的当月数据
     */
    @Async("TaskExecutor")
    @Transactional
    @Scheduled(cron = "0 0 4 * * ?")
    //@Scheduled(initialDelay = 5000, fixedRate = 86400000) // 5秒后首次执行，之后每天执行一
    @RedisLock(key = "task:Finance.ScheduleUpdateDeptProd")
    public void ScheduleUpdateDeptProd() throws ServiceErrorException {
        log.info("定时任务执行开始, 更新开始：");

        //1.获取当前年月
        //获取当月的年份和年月，如2025年2月，则年份为"2025"，年月为"202502"
        YearMonth currentYearMonth = YearMonth.now();
        String year = String.valueOf(currentYearMonth.getYear());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
        String yearMonth = currentYearMonth.format(formatter);

        //2.查询 YP_YEAR_MONTH 是否存在今年的数据；存在就不管，不存在就新增今年从1月到12月的数据
        int yearCount = generateProdReportMapper.countYpYearMonth(year);
        if(yearCount == 0){
            List<String> monthList = new ArrayList<>();
            for (int i = 0; i < 12; i++) {
                if(i < 9){
                    monthList.add(year + "0" + (i+1));
                }else{
                    monthList.add(year + (i+1));
                }
            }
            generateProdReportMapper.insertYpYearMonthBatch(year,monthList);
        }
        //查询 YP_YEAR_DAY 是否存在今年的数据；存在就不管，不存在就新增今年从1月1号到12月最后一天的数据
        int dayCount = generateProdReportMapper.countYpYearDay(year);
        if (dayCount == 0) {
            List<YearDay> yearDayList = new ArrayList<>();
            // 获取该年所有天数
            Year y = Year.of(Integer.parseInt(year));
            for (LocalDate date = y.atMonth(1).atDay(1);
                 !date.isAfter(y.atMonth(12).atEndOfMonth());
                 date = date.plusDays(1)) {
                yearDayList.add(new YearDay(year, date));
            }

            // 批量插入数据
            generateProdReportMapper.insertYpYearDayBatch(year,yearDayList);
        }


        // 3.删除现有月份的产量数据
        int count1 = generateProdReportMapper.deleteDhDeptProdStatusByCompanyAndMonth(yearMonth);
        int count2 = generateProdReportMapper.deleteDhDeptProdStatusMByCompanyAndMonth(yearMonth);
        int count3 = generateProdReportMapper.deleteDhDeptProdStatusDByCompanyAndMonth(yearMonth);

        // 3.检查该公司 DhDeptProdStatusM 是否有月份记录
        //1》第一次初始化所有
        int cnt = generateProdReportMapper.countByCompany(null);
        //2》初始化现有月份数据
        int cnt2 = generateProdReportMapper.countByCompany(yearMonth);

        if (cnt == 0 ) {
            // 插入 DhDeptProdStatusM 初始数据
            generateProdReportMapper.insertMonthInitialData2();
            generateProdReportMapper.insertDayInitialData2();

            generateProdReportMapper.updateMonthProd2();
            generateProdReportMapper.updateDayProd2();
        } else if(cnt2 == 0){
            // 插入 DhDeptProdStatusM/DhDeptProdStatusD 初始数据（现有月份的数据）
            generateProdReportMapper.insertMonthInitialData( year, yearMonth);
            generateProdReportMapper.insertDayInitialData( year, yearMonth);
            //2.更新当月产量
            generateProdReportMapper.updateMonthProd(yearMonth);
            //3.更新当月日产量
            generateProdReportMapper.updateDayProd(yearMonth);
        }else{
            //1.更新当月产量
            generateProdReportMapper.updateMonthProd(yearMonth);
            //2.更新日产量
            generateProdReportMapper.updateDayProd(yearMonth);
        }

        // 插入日志记录
        generateProdReportMapper.insertDhNewExecuteLog("2.1");

        log.info("定时任务执行成功,  结束");
    }

    /**
     * 部门生产状况
     * 2.2 月/月生产状况
     * 每个月1号4点半更新上个月的数据
     */
    @Async("TaskExecutor")
    @Transactional
    @Scheduled(cron = "0 30 4 1 * ?")
    @RedisLock(key = "task:Finance.ScheduleUpdateDeptProd")
    public void ScheduleUpdateDhDeptProdLast() throws ServiceErrorException {
        log.info("定时任务执行开始, 更新开始：");

        //1.计算昨天的日期
        LocalDate yesterday = LocalDate.now().minus(1, ChronoUnit.DAYS);

        // 获取昨天的年份和年月
        String year = String.valueOf(yesterday.getYear());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
        String yearMonth = yesterday.format(formatter);

        //2.查询 YP_YEAR_MONTH 是否存在今年的数据；存在就不管，不存在就新增今年从1月到12月的数据
        int yearCount = generateProdReportMapper.countYpYearMonth(year);
        if(yearCount == 0){
            List<String> monthList = new ArrayList<>();
            for (int i = 0; i < 12; i++) {
                if(i < 9){
                    monthList.add(year + "0" + (i+1));
                }else{
                    monthList.add(year + (i+1));
                }
            }
            generateProdReportMapper.insertYpYearMonthBatch(year,monthList);
        }
        //查询 YP_YEAR_DAY 是否存在今年的数据；存在就不管，不存在就新增今年从1月1号到12月最后一天的数据
        int dayCount = generateProdReportMapper.countYpYearDay(year);
        if (dayCount == 0) {
            List<YearDay> yearDayList = new ArrayList<>();
            // 获取该年所有天数
            Year y = Year.of(Integer.parseInt(year));
            for (LocalDate date = y.atMonth(1).atDay(1);
                 !date.isAfter(y.atMonth(12).atEndOfMonth());
                 date = date.plusDays(1)) {
                yearDayList.add(new YearDay(year, date));
            }

            // 批量插入数据
            generateProdReportMapper.insertYpYearDayBatch(year,yearDayList);
        }


        // 3.删除现有月份的产量数据
        int count1 = generateProdReportMapper.deleteDhDeptProdStatusByCompanyAndMonth(yearMonth);
        int count2 = generateProdReportMapper.deleteDhDeptProdStatusMByCompanyAndMonth(yearMonth);
        int count3 = generateProdReportMapper.deleteDhDeptProdStatusDByCompanyAndMonth(yearMonth);

        // 3.检查该公司 DhDeptProdStatusM 是否有月份记录
        //1》第一次初始化所有
        int cnt = generateProdReportMapper.countByCompany(null);
        //2》初始化现有月份数据
        int cnt2 = generateProdReportMapper.countByCompany(yearMonth);

        if (cnt == 0 ) {
            // 插入 DhDeptProdStatusM 初始数据
            generateProdReportMapper.insertMonthInitialData2();
            generateProdReportMapper.insertDayInitialData2();

            generateProdReportMapper.updateMonthProd2();
            generateProdReportMapper.updateDayProd2();
        } else if(cnt2 == 0){
            // 插入 DhDeptProdStatusM/DhDeptProdStatusD 初始数据（现有月份的数据）
            generateProdReportMapper.insertMonthInitialData( year, yearMonth);
            generateProdReportMapper.insertDayInitialData( year, yearMonth);
            //2.更新当月产量
            generateProdReportMapper.updateMonthProd(yearMonth);
            //3.更新当月日产量
            generateProdReportMapper.updateDayProd(yearMonth);
        }else{
            //1.更新当月产量
            generateProdReportMapper.updateMonthProd(yearMonth);
            //2.更新日产量
            generateProdReportMapper.updateDayProd(yearMonth);
        }

        // 插入日志记录
        generateProdReportMapper.insertDhNewExecuteLog("2.2");

        log.info("定时任务执行成功,  结束");
    }

}


